import requests
from urllib.parse import urlencode

import demixed.utils
import demixed.track
import demixed.artist
import demixed.album

class Deezer:
  def __init__(self):
    self.session = requests.Session()
    self.http_headers = {
      "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36",
      "Content-Language": "en-US",
      "Cache-Control": "max-age=0",
      "Accept": "*/*",
      "Accept-Charset": "utf-8,ISO-8859-1;q=0.7,*;q=0.3",
      "Accept-Language": "en-US,en;q=0.9,en-US;q=0.8,en;q=0.7",
      "Connection": 'keep-alive'
    }
    self.user = None

  def call_private_api(self, method, args = {}):
    query_string = {
      "api_version": "1.0",
      "api_token": "null",
      "input": "3",
      "method": method
    }

    if method != "deezer.getUserData":
      query_string["api_token"] = self.get_api_token()

    return self.session.post(
      demixed.utils.PRIVATE_API_URL % urlencode(query_string),
      data = args,
      headers = self.http_headers
    ).json()

  def get_api_token(self):
    json = self.call_private_api("deezer.getUserData")
    if "checkFormLogin" in json["results"]:
      return json["results"]["checkFormLogin"]
    elif "checkForm" in json["results"]:
      return json["results"]["checkForm"]
    else:
      raise "couldn't get api_token"

  def _post_login(self):
    """The function to call after login cookies have been set.
    It will make sure all cookies are set, and returns the user profile.
    It's not supposed to be called on normal usage."""
    result = self.session.get("https://www.deezer.com/", headers=self.http_headers)
    if result.status_code != 200:
      raise "couldn't load deezer.com"

    result = self.call_private_api('deezer.getUserData')
    user_data = result["results"]["USER"]
    self.user = {
      "id": user_data["USER_ID"],
      "name": user_data["BLOG_NAME"],
    }
    if "USER_PICTURE" in user_data:
      self.user["picture_url"] = demixed.utils.USER_PICTURES_URL % user_data["USER_PICTURE"]
    return self.user

  def login_with_cookie(self, cookie_string):
    cookie = {"arl": cookie_string}
    self.session.cookies.update(cookie)
    return self._post_login()

  def login(self, mail, password):
    login_token = self.get_api_token()

    json = {
      "type": "login",
      "mail": mail,
      "password": password,
      "checkFormLogin": login_token,
      "reCaptchaToken": "",
      "reCaptchaDisabled": 1
    }
    headers = {
      **self.http_headers,
      "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8"
    }

    result = self.session.post(
      'https://www.deezer.com//ajax/action.php?',
      data = json,
      headers = headers,
    )
    if result.text != "success":
      raise 'wrong email or password'

    return self._post_login()

  def get_track_data(self, track_id):
    if track_id < 0:
      return self.call_private_api(
        'song.getData',
        args = '{"SNG_ID": %i}' % track_id
      )
    else:
      return self.call_private_api(
        'deezer.pageTrack',
        args = '{"SNG_ID": %i}' % track_id
      )
  def get_track(self, track_id):
    return demixed.track.DeezerTrack.grab_or_create(
      track_id,
      raw_data = self.get_track_data(track_id)["results"]["DATA"]
    )

  def get_artist_data(self, artist_id):
    return self.call_private_api(
      'deezer.pageArtist',
      args = '{"ART_ID": %i, "LANG": "EN"}' % artist_id
    )
  def get_artist(self, artist_id):
    return demixed.artist.DeezerArtist.grab_or_create(
      artist_id,
      raw_data = self.get_artist_data(artist_id)["results"]
    )

  def get_album_data(self, album_id):
    return self.call_private_api(
      'deezer.pageAlbum',
      args = '{"ALB_ID": %i, "LANG": "EN"}' % album_id
    )
  def get_album(self, album_id):
    return demixed.album.DeezerAlbum.grab_or_create(
      album_id,
      raw_data = self.get_album_data(album_id)["results"]
    )

